﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;

namespace SchEdu.Framework.DataModel
{

    public class OperationList : List<SchEduDataSet.OperationRow>
    {
        public OperationList()
            : base()
        {
        }

        public OperationList(OperationList operations)
            : base(operations)
        {
        }

        public OperationList(SchEduDataSet.OperationRow[] operations)
            : base(operations)
        {
        }

        public OperationList(SchEduDataSet.OperationDataTable operations)
        {
            foreach (SchEduDataSet.OperationRow operation in operations)
            {
                Add(operation);
            }
        }

        public OperationList(IEnumerable<SchEduDataSet.OperationRow> operations)
        {
            foreach (SchEduDataSet.OperationRow operation in operations)
            {
                Add(operation);
            }
        }


        public SchEduDataSet.OperationRow FindByID(int ID)
        {
            foreach (SchEduDataSet.OperationRow operation in this)
            {
                if (ID == operation.ID)
                {
                    return operation;
                }
            }
            return null;
        }

        public bool HasOperationForOrder(SchEduDataSet.OrderRow order)
        {
            foreach (SchEduDataSet.OperationRow operation in this)
            {
                if (operation.OrderID == order.ID)
                {
                    return true;
                }
            }
            return false;
        }

        public int GetProcessingTime(SchEduDataSet.OrderRow order)
        {
            int processingTime = 0;
            foreach (SchEduDataSet.OperationRow operation in order.GetOperationRows())
            {
                processingTime += operation.ProcessingTime;
            }
            return processingTime;
        }

        public int GetProcessingTime()
        {
            int processingTime = 0;
            foreach (SchEduDataSet.OperationRow operation in this)
            {
                processingTime += operation.ProcessingTime;
            }
            return processingTime;
        }

        public int GetStartDate(SchEduDataSet.OrderRow order)
        {
            int startDate = 0;
            foreach (SchEduDataSet.OperationRow operation in order.GetOperationRows())
            {
                startDate = Math.Min(startDate, operation.StartDate);
            }
            return startDate;
        }

        public int GetStartDate()
        {
            int startDate = 0;
            foreach (SchEduDataSet.OperationRow operation in this)
            {
                startDate = Math.Min(startDate, operation.StartDate);
            }
            return startDate;
        }

        public int GetEndDate(SchEduDataSet.OrderRow order)
        {
            int endDate = 0;
            foreach (SchEduDataSet.OperationRow operation in order.GetOperationRows())
            {
                endDate = Math.Max(endDate, operation.EndDate);
            }
            return endDate;
        }

        public int GetEndDate()
        {
            int endDate = 0;
            foreach (SchEduDataSet.OperationRow operation in this)
            {
                endDate = Math.Max(endDate, operation.EndDate);
            }
            return endDate;
        }

        public int ProcessingTime()
        {
            int processingTime = 0;
            foreach (SchEduDataSet.OperationRow operation in this)
            {
                processingTime += operation.ProcessingTime;
            }
            return processingTime;
        }

        public SchEduDataSet.OperationRow MinProcessingTime()
        {
            SchEduDataSet.OperationRow minOperation = null;
            int minProcessingTime = Int32.MaxValue;
            foreach (SchEduDataSet.OperationRow operation in this)
            {
                if (operation.ProcessingTime < minProcessingTime)
                {
                    minProcessingTime = operation.ProcessingTime;
                    minOperation = operation;
                }
            }
            return minOperation;
        }

        public SchEduDataSet.OperationRow MaxProcessingTime()
        {
            SchEduDataSet.OperationRow maxOperation = null;
            int maxProcessingTime = Int32.MinValue;
            foreach (SchEduDataSet.OperationRow operation in this)
            {
                if (operation.ProcessingTime > maxProcessingTime)
                {
                    maxProcessingTime = operation.ProcessingTime;
                    maxOperation = operation;
                }
            }
            return maxOperation;
        }


        public SchEduDataSet.OperationRow MinWeight()
        {
            SchEduDataSet.OperationRow weightOperation = null;
            int weight = Int32.MaxValue;
            foreach (SchEduDataSet.OperationRow operation in this)
            {
                if (operation.OrderRow.Weight < weight)
                {
                    weight = operation.OrderRow.Weight;
                    weightOperation = operation;
                }
            }
            return weightOperation;
        }

        public SchEduDataSet.OperationRow MaxWeight()
        {
            SchEduDataSet.OperationRow weightOperation = null;
            int weight = Int32.MinValue;
            foreach (SchEduDataSet.OperationRow operation in this)
            {
                if (operation.OrderRow.Weight > weight)
                {
                    weight = operation.OrderRow.Weight;
                    weightOperation = operation;
                }
            }
            return weightOperation;
        }

        public OperationList GetAvailableAt(int t)
        {
            OperationList operations = new OperationList();
            foreach (SchEduDataSet.OperationRow op in this)
            {
                if (op.AvailabilityDate <= t)
                {
                    operations.Add(op);
                }
            }
            return operations;
        }

        public SchEduDataSet.OperationRow GetFirstAvailable()
        {
            SchEduDataSet.OperationRow operation = null;
            foreach (SchEduDataSet.OperationRow op in this)
            {
                if (operation == null)
                {
                    operation = op;
                }
                if (op.AvailabilityDate < operation.AvailabilityDate)
                {
                    operation = op;
                }
            }
            return operation;
        }

        public void SortByEDD()
        {
            Sort(new EDDComparer());
        }

        public void SortBySequenceNo()
        {
            Sort(new SequenceNoComparer());
        }

        public void SortByProcessingTime()
        {
            Sort(new ProcessingTimeComparer());
        }


        class SequenceNoComparer : Comparer<SchEduDataSet.OperationRow>
        {

            public override int Compare(SchEduDataSet.OperationRow x, SchEduDataSet.OperationRow y)
            {
                if (x.SequenceNo < y.SequenceNo)
                {
                    return -1;
                }
                if (x.SequenceNo > y.SequenceNo)
                {
                    return 1;
                }
                return 0;
            }
        }

        class ProcessingTimeComparer : Comparer<SchEduDataSet.OperationRow>
        {

            public override int Compare(SchEduDataSet.OperationRow x, SchEduDataSet.OperationRow y)
            {
                if (x.ProcessingTime < y.ProcessingTime)
                {
                    return -1;
                }
                if (x.ProcessingTime > y.ProcessingTime)
                {
                    return 1;
                }
                return 0;
            }
        }

        class EDDComparer : Comparer<SchEduDataSet.OperationRow>
        {

            public override int Compare(SchEduDataSet.OperationRow x, SchEduDataSet.OperationRow y)
            {
                if (x.DueDate < y.DueDate)
                {
                    return -1;
                }
                if (x.DueDate > y.DueDate)
                {
                    return 1;
                }
                return 0;
            }
        }


    }


}
